package com.legal.aid.app.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.legal.aid.app.config.WebSocketServer;
import com.legal.aid.app.domain.dto.CommentAddDto;
import com.legal.aid.app.domain.dto.CommentDto;
import com.legal.aid.app.domain.dto.CommentLikeDto;
import com.legal.aid.app.domain.vo.CommentVo;
import com.legal.aid.app.mapper.AppCommentMapper;
import com.legal.aid.app.service.IAppCommentService;
import com.legal.aid.common.constant.CacheConstants;
import com.legal.aid.common.core.domain.entity.CommonUser;
import com.legal.aid.common.core.domain.model.AppLoginUser;
import com.legal.aid.common.core.redis.RedisCache;
import com.legal.aid.common.exception.ServiceException;
import com.legal.aid.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class AppCommentServiceImpl implements IAppCommentService {

    @Autowired
    private AppCommentMapper commentMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WebSocketServer webSocketServer;

    @Override
    public List<CommentVo> selectCommentList(CommentDto commentDto) {
        // 参数校验
        if (commentDto == null ||
                commentDto.getTargetId() == null ||
                commentDto.getTargetType() == null) {
            return Collections.emptyList();
        }

        // 获取评论列表
        List<CommentVo> commentList = commentMapper.selectCommentList(commentDto);

        // 获取当前登录用户
        AppLoginUser appLoginUser = SecurityUtils.getAppLoginUser();
        if (appLoginUser != null) {
            CommonUser commonUser = appLoginUser.getCommonUser();
            String targetTypeStr = "1".equals(commentDto.getTargetType()) ? "newsComment" : "caseComment";

            // 批量检查每条评论是否被当前用户点赞
            for (CommentVo comment : commentList) {
                String likeKey = CacheConstants.COMMENT_LIKE_PREFIX + targetTypeStr + ":" +
                        comment.getCommentId() + ":" + commonUser.getId();
                String countKey = CacheConstants.COMMENT_COUNT_PREFIX + targetTypeStr + ":" +
                        comment.getCommentId();
                //该条评论的点赞数
                comment.setLikeCount(redisCache.getCacheObject(countKey));
                // 如果Redis中存在点赞记录，则标记为已点赞
                comment.setIsLiked(redisCache.hasKey(likeKey) ? "1" : "0");
            }
        }

        return commentList;
    }

    @Override
    public int insertComment(CommentAddDto commentAddDto, Long userId) {
        // 构建评论对象
        String targetStr = commentAddDto.getTargetType().equals("news") ? "1" : "2";
        CommentVo comment = new CommentVo();
        comment.setTargetId(commentAddDto.getTargetId());
        comment.setTargetType(targetStr);
        comment.setCommentContent(commentAddDto.getCommentContent());
        comment.setUserId(userId);
        comment.setLikeCount(0);
        comment.setIsDeleted("0");
        comment.setIsApproved("1"); // 默认审核通过

        // 保存评论
        return commentMapper.insertComment(comment);
    }

    /**
     * 获取评论数量
     */
    @Override
    public int getCommentCount(String targetType, Long targetId) {
        String cacheKey = CacheConstants.COMMENT_COUNT_PREFIX + targetType + ":" + targetId;

        // 先从缓存获取
        Integer count = redisCache.getCacheObject(cacheKey);
        if (count != null) {
            return count;
        }

        // 缓存未命中，从数据库查询
        CommentDto query = new CommentDto();
        query.setTargetType(targetType);
        query.setTargetId(targetId.toString());
        List<CommentVo> comments = commentMapper.selectCommentList(query);
        count = comments.size();

        // 更新缓存，设置过期时间
        redisCache.setCacheObject(cacheKey, count, 1, TimeUnit.HOURS);

        return count;
    }

    /**
     * 评论点赞
     */
    @Override
    public String likeComment(CommentLikeDto commentLikeDto) {
        if (commentLikeDto == null ||
                commentLikeDto.getCommentId() == null ||
                commentLikeDto.getTargetType() == null) {
            return "点赞失败";
        }

        AppLoginUser appLoginUser = SecurityUtils.getAppLoginUser();
        CommonUser commonUser = appLoginUser.getCommonUser();
        String targetTypeStr = "news".equals(commentLikeDto.getTargetType()) ? "newsComment" : "caseComment";

        // 构建点赞记录key
        String likeKey = CacheConstants.COMMENT_LIKE_PREFIX + targetTypeStr + ":" +
                commentLikeDto.getCommentId() + ":" + commonUser.getId();

        // 构建点赞数量key
        String countKey = CacheConstants.COMMENT_COUNT_PREFIX + targetTypeStr + ":" +
                commentLikeDto.getCommentId();

        // 检查是否已经点赞
        if (redisCache.hasKey(likeKey)) {
            // 点赞过，再次点赞，删除redis点赞记录
            redisCache.deleteObject(likeKey);
            // 减少点赞数
            redisCache.increment(countKey, -1);
            // 设置点赞数量的过期时间
            redisCache.expire(countKey, 24 * 60 * 60, TimeUnit.SECONDS);
            return "点赞已取消";
        }

        try {
            // 记录点赞
            redisCache.setCacheObject(likeKey, 1, 24 * 60 * 60, TimeUnit.SECONDS);
            // 增加点赞数
            redisCache.increment(countKey, 1);
            // 设置点赞数量的过期时间
            redisCache.expire(countKey, 24 * 60 * 60, TimeUnit.SECONDS);

            // 获取评论信息，用于通知
            CommentVo comment = commentMapper.selectCommentById(Long.parseLong(commentLikeDto.getCommentId()));
            if (comment != null && !comment.getUserId().equals(commonUser.getId())) {
                // 构建通知消息
                JSONObject notification = new JSONObject();
                notification.put("type", "like");
                notification.put("title", "收到点赞");
                notification.put("content", commonUser.getUserName() + "点赞了您的评论");
                notification.put("commentId", commentLikeDto.getCommentId());
                notification.put("commentContent", comment.getCommentContent());
                notification.put("timestamp", new Date().getTime());

                // 发送WebSocket通知
                webSocketServer.sendToClient(comment.getUserId().toString(), notification.toJSONString());
            }

            return "点赞成功";
        } catch (Exception e) {
            throw new ServiceException("点赞失败");
        }
    }

}
